package com.shanling.shanlingcontroller.manager;

import android.os.Handler;
import android.util.Log;
import android.widget.ListView;

import com.chipsguide.lib.bluetooth.entities.BluetoothDeviceMusicSongEntity;
import com.chipsguide.lib.bluetooth.managers.BluetoothDeviceManager;
import com.chipsguide.lib.bluetooth.managers.BluetoothDeviceMusicManager;
import com.shanling.shanlingcontroller.CustomApplication;
import com.shanling.shanlingcontroller.bean.Music;
import com.shanling.shanlingcontroller.ui.activity.DeviceMusicActivity;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.disposables.Disposable;

/**
 * Created by xiaobai on 2019/12/12.
 */

public class DeviceMusicManager {

    private static final int LOAD_STEP = 20;

    private static DeviceMusicManager sInstance;
    private BluetoothDeviceManager mBluetoothDeviceManager;
    private onDeviceModeChangedListener mDeviceModeChangedListener;
    private List<OnDeviceMusicSongChangedListener> mDeviceMusicSongChangedListeners;
    private BluetoothDeviceMusicManager.IBluetoothDeviceMusicManager mDeviceMusicManager;
    private List<BluetoothDeviceMusicSongEntity> mDeviceMusicSongEntities;
    private Handler mDeviceMusicListHandler = new Handler();
    private Disposable mDisposable;

    public static DeviceMusicManager getInstance(){
        if (sInstance == null){
            sInstance = new DeviceMusicManager();
        }
        return sInstance;
    }

    private DeviceMusicManager(){
        mDeviceMusicSongEntities = new ArrayList<>();
        mDeviceMusicSongChangedListeners = new ArrayList<>();
        mBluetoothDeviceManager = CustomApplication.getInstance().getBluetoothDeviceManager();
    }

    public List<BluetoothDeviceMusicSongEntity> getDeviceMusicSongEntities(){
        return mDeviceMusicSongEntities;
    }

    public void destroy(){
        if (mDeviceMusicListHandler != null){
            mDeviceMusicListHandler.removeCallbacks(runnable);
        }
        mDeviceMusicSongEntities.clear();
        if(mDisposable!=null){
            mDisposable.dispose();
        }

    }

    public int getBluetoothDeviceMode(){
        return mBluetoothDeviceManager == null ? 0 : mBluetoothDeviceManager.getCurrentMode();
    }

    public void setOnBluetoothDeviceCardMusicManagerReadyListener() {
        if (mBluetoothDeviceManager != null) {
            mBluetoothDeviceManager.setOnBluetoothDeviceCardMusicManagerReadyListener(cardMusicReadyListener);
        }
    }

    private BluetoothDeviceManager.OnBluetoothDeviceCardMusicManagerReadyListener cardMusicReadyListener = new BluetoothDeviceManager.OnBluetoothDeviceCardMusicManagerReadyListener() {
        @Override
        public void onBluetoothDeviceCardMusicManagerReady() {
            if (mBluetoothDeviceManager != null){
                mDeviceMusicManager = mBluetoothDeviceManager.getBluetoothDeviceCardMusicManager();
                mDeviceMusicManager.setOnBluetoothDeviceMusicLoopModeChangedListener(deviceMusicLoopModeChangedListener);
                mDeviceMusicManager.setOnBluetoothDeviceMusicPlayStateChangedListener(deviceMusicPlayStateChangedListener);
                mDeviceMusicManager.setOnBluetoothDeviceMusicSongChangedListener(deviceMusicSongChangedListener);
                getDeviceMusics();
            }
        }
    };

    private void getDeviceMusics(){
        int total = mDeviceMusicManager.getSongSize();
        int plistSize = mDeviceMusicSongEntities.size();
        Log.e("MISS", " getDeviceMusics ---- " + plistSize + " --- " + total);
        if (plistSize < total){
            int selectSize = total - plistSize;
            if (mDeviceMusicManager != null){
                mDeviceMusicManager.getSongList(plistSize + 1, Math.min(LOAD_STEP, selectSize), bluetoothDeviceMusicSongListChangedListener);
            }
        }
    }

    private Runnable runnable = this::getDeviceMusics;

    private BluetoothDeviceMusicManager.OnBluetoothDeviceMusicSongListChangedListener bluetoothDeviceMusicSongListChangedListener = new BluetoothDeviceMusicManager.OnBluetoothDeviceMusicSongListChangedListener() {
        @Override
        public void onBluetoothDeviceMusicSongListChanged(List<BluetoothDeviceMusicSongEntity> bluetoothDeviceMusicSongEntityList) {
            for (BluetoothDeviceMusicSongEntity entity : bluetoothDeviceMusicSongEntityList){
                Log.e("MISS","onDeviceMusicSongListChanged --- " + entity.getTitle() + " --- " + entity.getGenre() + " --- " + entity.getMimeType() + " --- " + entity.getAlbum() + " --- " + entity.getArtist() + " --- " + entity.getName());
            }
            mDeviceMusicSongEntities.addAll(bluetoothDeviceMusicSongEntityList);
            for (OnDeviceMusicSongChangedListener musicSongChangedListener : mDeviceMusicSongChangedListeners){
                musicSongChangedListener.onDeviceMusicSongListChanged();
            }
            mDeviceMusicListHandler.post(runnable);
        }
    };

    private BluetoothDeviceMusicManager.OnBluetoothDeviceMusicLoopModeChangedListener deviceMusicLoopModeChangedListener = new BluetoothDeviceMusicManager.OnBluetoothDeviceMusicLoopModeChangedListener() {
        @Override
        public void onBluetoothDeviceMusicLoopModeChanged(int mode) {
            for (OnDeviceMusicSongChangedListener musicSongChangedListener : mDeviceMusicSongChangedListeners){
                musicSongChangedListener.onDeviceMusicLoopModeChanged(mode);
            }
        }
    };

    private BluetoothDeviceMusicManager.OnBluetoothDeviceMusicPlayStateChangedListener deviceMusicPlayStateChangedListener = new BluetoothDeviceMusicManager.OnBluetoothDeviceMusicPlayStateChangedListener() {
        @Override
        public void onBluetoothDeviceMusicPlayStateChanged(int i) {
            for (OnDeviceMusicSongChangedListener musicSongChangedListener : mDeviceMusicSongChangedListeners){
                musicSongChangedListener.onDeviceMusicPlayStateChanged(i);
            }
        }
    };

    private BluetoothDeviceMusicManager.OnBluetoothDeviceMusicSongChangedListener deviceMusicSongChangedListener = new BluetoothDeviceMusicManager.OnBluetoothDeviceMusicSongChangedListener() {
        @Override
        public void onBluetoothDeviceMusicSongChanged(BluetoothDeviceMusicSongEntity bluetoothDeviceMusicSongEntity) {
            for (OnDeviceMusicSongChangedListener musicSongChangedListener : mDeviceMusicSongChangedListeners){
                musicSongChangedListener.onDeviceMusicSongChanged(bluetoothDeviceMusicSongEntity);
            }
        }
    };

    public void addOnDeviceMusicSongChangedListener(OnDeviceMusicSongChangedListener deviceMusicSongChangedListener){
        if (!mDeviceMusicSongChangedListeners.contains(deviceMusicSongChangedListener)){
            mDeviceMusicSongChangedListeners.add(deviceMusicSongChangedListener);
        }
    }

    public void removeOnDeviceMusicSongChangedListener(OnDeviceMusicSongChangedListener deviceMusicSongChangedListener){
        if (mDeviceMusicSongChangedListeners.contains(deviceMusicSongChangedListener)){
            mDeviceMusicSongChangedListeners.remove(deviceMusicSongChangedListener);
        }
    }

    public void setOnDeviceModeChangedListener(onDeviceModeChangedListener listener){
        this.mDeviceModeChangedListener = listener;
    }

    public void getDeviceMode(int mode){
        if (mDeviceModeChangedListener != null){
            mDeviceModeChangedListener.onDeviceModeChanged(mode);
        }
    }

    public void selectPlay(int index){
        if (mDeviceMusicManager != null){
            mDeviceMusicManager.select(index);
        }
    }

    public int getCurrentLoopMode(){
        return mDeviceMusicManager == null ? 0 : mDeviceMusicManager.getCurrentLoopMode();
    }

    public int getCurrentPlayState(){
        return mDeviceMusicManager == null ? 0 : mDeviceMusicManager.getCurrentPlayState();
    }

    public int getCurrentSongCurrentPosition(){
        return mDeviceMusicManager == null ? 0 : mDeviceMusicManager.getCurrentSongCurrentPosition();
    }

    public int getCurrentSongDuration(){
        return mDeviceMusicManager == null ? 0 : mDeviceMusicManager.getCurrentSongDuration();
    }

    public BluetoothDeviceMusicSongEntity getCurrentSong(){
        return mDeviceMusicManager == null ? null : mDeviceMusicManager.getCurrentSong();
    }

    public void play(){
        if (mDeviceMusicManager != null){
            mDeviceMusicManager.play();
        }
    }

    public void pause(){
        if (mDeviceMusicManager != null){
            mDeviceMusicManager.pause();
        }
    }

    public void previous(){
        if (mDeviceMusicManager != null){
            mDeviceMusicManager.previous();
        }
    }

    public void next(){
        if (mDeviceMusicManager != null){
            mDeviceMusicManager.next();
        }
    }

    public void setLoopMode(int loopMode){
        if (mDeviceMusicManager != null){
            mDeviceMusicManager.setLoopMode(loopMode);
        }
    }

    public void getProgressUpdate(){
        Log.e("MISS", "getProgressUpdate");
        mDisposable = io.reactivex.Observable
                .interval(500, TimeUnit.MILLISECONDS)
                .subscribeOn(io.reactivex.schedulers.Schedulers.io())
                .observeOn(io.reactivex.android.schedulers.AndroidSchedulers.mainThread())
                .subscribe(v -> {
                    Log.e("MISS", "onDeviceMusicProgressUpdate");
                    for (OnDeviceMusicSongChangedListener musicSongChangedListener : mDeviceMusicSongChangedListeners){
                        musicSongChangedListener.onDeviceMusicProgressUpdate(getCurrentSongCurrentPosition(), getCurrentSongDuration());
                    }
                });
    }

    public interface OnDeviceMusicSongChangedListener{
        void onDeviceMusicSongListChanged();
        void onDeviceMusicLoopModeChanged(int mode);
        void onDeviceMusicPlayStateChanged(int playState);
        void onDeviceMusicSongChanged(BluetoothDeviceMusicSongEntity bluetoothDeviceMusicSongEntity);
        void onDeviceMusicProgressUpdate(int currentPosition, int duration);
    }

    public interface onDeviceModeChangedListener{
        void onDeviceModeChanged(int mode);
    }
}
